/**
 * 绘图区管理 - 符合utility.mdr规则
 */
import { CircuitElement, Wire, IHitTestable, HitType, HitTestResult, IPin, ConnectionManager, ConnectionState, ConnectionStyle, injectConnectionStyles } from '../circuit-elements.js';
import { dragManager, sceneHitTester, globalMgr } from '../globalMgr.js';
import { Resistor, Capacitor, VoltageSource, CurrentSource } from '../circuit-elements.js';
import { PropertyPanel } from './PropertyPanel.js';
import { CanvasContentPanel } from './CanvasContentPanel.js';
import { WireManager } from './WireManager.js';

export class CanvasManager {
    private canvas: SVGSVGElement;
    private elements: CircuitElement[] = [];
    private wires: Wire[] = [];
    private propertyPanel: PropertyPanel;
    private connectionManager: ConnectionManager;
    private contentPanel: CanvasContentPanel;
    private wireManager: WireManager;
    
    // 分区管理
    private gridSize = 500; // 分区大小(px)
    private partitions: Map<string, CircuitElement[]> = new Map(); // 分区索引
    
    // 连线样式配置
    private connectionStyle: ConnectionStyle = ConnectionStyle.Straight;
    
    // 画布变换相关
    private viewportTransform = { x: 0, y: 0, scale: 1 }; // 视口变换（平移和缩放）
    private isDraggingCanvas = false;
    private dragStartPoint = { x: 0, y: 0 };
    private dragStartTransform = { x: 0, y: 0 };
    private canvasContainer: SVGGElement; // 画布内容容器
    private getPartitionKey(x: number, y: number): string {
        const gridX = Math.floor(x / this.gridSize);
        const gridY = Math.floor(y / this.gridSize);
        return `${gridX},${gridY}`;
    }

    constructor(container: HTMLElement) {
        // 注入连接系统样式
        injectConnectionStyles();
        
        // 创建SVG画布
        this.canvas = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        
        // 暴露实例到全局，供Wire类使用
        (window as any).canvasManager = this;
        this.canvas.style.width = '100%';
        this.canvas.style.height = '600px';

        // 添加可见边框
        this.canvas.style.border = '2px solid #ccc';
        this.canvas.style.borderRadius = '8px';
        this.canvas.style.backgroundColor = '#f8f9fa';
        this.canvas.style.zIndex = '0'; // 确保画布在默认层级
        this.canvas.style.cursor = 'grab'; // 设置画布拖动光标

        container.appendChild(this.canvas);

        // 创建画布内容容器，用于整体变换
        this.canvasContainer = document.createElementNS('http://www.w3.org/2000/svg', 'g');
        this.canvasContainer.setAttribute('id', 'canvas-container');
        this.canvas.appendChild(this.canvasContainer);

        // 设置画布原点在编辑器窗口正中间
        this.setupCanvasOrigin();
        
        // 初始化Wire管理器
        this.wireManager = new WireManager();
        
        // 设置Wire管理器的画布容器
        this.wireManager.setCanvasContainer(this.canvasContainer);

        // 初始化连接管理器
        this.connectionManager = new ConnectionManager();
        
        // 设置默认连线样式
        this.connectionManager.setConnectionStyle(this.connectionStyle);
        
        // 扩展连接管理器的位置查找功能
        (this.connectionManager as any).findPinAtPosition = (x: number, y: number): IPin | null => {
            return this.findPinAtPosition(x, y);
        };
        
        // 设置画布变换回调，让ConnectionManager能够正确计算坐标
        (this.connectionManager as any).getCanvasOffset = () => {
            return this.viewportTransform;
        };
        (this.connectionManager as any).screenToCanvas = (screenX: number, screenY: number) => {
            return this.screenToCanvas(screenX, screenY);
        };
        // 为连接线提供世界坐标转换（不考虑viewportTransform）
        (this.connectionManager as any).screenToWorld = (screenX: number, screenY: number) => {
            const pt = this.canvas.createSVGPoint();
            pt.x = screenX;
            pt.y = screenY;
            const svgP = pt.matrixTransform(this.canvas.getScreenCTM()?.inverse());
            return { x: svgP.x, y: svgP.y };
        };
        
        // 初始化属性面板
        this.propertyPanel = new PropertyPanel(container);
        
        // 初始化画布内容面板
        this.contentPanel = new CanvasContentPanel(container, this);
        
        // 初始化Wire管理器
        this.wireManager = new WireManager();
        
        this.setupEventListeners();
        this.setupDragAndDrop();
        this.setupCanvasDrag(); // 在最后设置画布拖动，确保其他事件先设置
        this.setupConnectionStyleListener();
        this.exposeDebugMethods();
    }

    addElement(element: CircuitElement | Wire): void {
        if (element instanceof Wire) {
            // 处理Wire类型
            this.wires.push(element);
            
            // 使用Wire的render方法获取SVG
            const wireSvg = element.render();
            this.canvasContainer.insertAdjacentHTML('beforeend', wireSvg);
            
            // 获取刚添加的元素组
            const elementGroup = this.canvasContainer.querySelector(`[data-element-id="${element.id}"]`) as SVGGElement;
            if (!elementGroup) {
                console.error('Failed to find created wire group for:', element.id);
                return;
            }

            this.setupElementDrag(elementGroup, element);
            
            // 注册到全局管理器和命中检测系统
            globalMgr.registerWire(element);
            sceneHitTester.register(element);
        } else {
            // 处理CircuitElement类型
            this.elements.push(element);
            
            // 直接将元件的SVG添加到画布容器，不需要额外的g包装
            // 因为元件的getSVG()已经包含了完整的transform信息
            this.canvasContainer.insertAdjacentHTML('beforeend', element.getSVG());
            
            // 获取刚添加的元素组
            const elementGroup = this.canvasContainer.querySelector(`[data-element-id="${element.id}"]`) as SVGGElement;
            if (!elementGroup) {
                console.error('Failed to find created element group for:', element.id);
                return;
            }

            // 确保只设置一次拖动功能
            if (!elementGroup.hasAttribute('data-drag-setup')) {
                this.setupElementDrag(elementGroup, element);
                elementGroup.setAttribute('data-drag-setup', 'true');
            }
            this.setupPinInteractions(elementGroup, element);
            
            // 将元件添加到对应分区
            this.updateElementPartition(element);
            
            // 注册到全局管理器和命中检测系统
            globalMgr.registerElement(element);
            sceneHitTester.register(element);
        }
    }

    /**
     * 设置元件拖动功能 - 被动渲染模式版本
     * 元件拖动时不再设置姿态数据，直接使用位置和旋转属性
     * 来自接口：ICircuitElement
     */
    private setupElementDrag(elementGroup: SVGGElement, element: CircuitElement | Wire): void {
        // 记录元件原始位置用于分区更新
        let lastPosition = element instanceof Wire ? 
            { x: 0, y: 0 } : // Wire不使用位置进行分区
            { ...element.position };

        // 被动模式拖动逻辑 - 使用直接的位置属性而不是姿态数据
        let isDragging = false;
        let startScreenPos = { x: 0, y: 0 };
        let startPosition = { x: 0, y: 0 };

        // 拖动节流优化
        let lastRenderTime = 0;
        const RENDER_THROTTLE = 16; // ~60fps

        let clickStartTime = 0;
        let hasDragged = false;

        elementGroup.addEventListener('mousedown', (e) => {
            const target = e.target as SVGElement;
            if (target.closest('circle[data-pin-id]')) {
                // 如果是引脚点击，不启动拖动
                return;
            }

            clickStartTime = Date.now();
            hasDragged = false;

            // 对于Wire元件，使用Wire自己的拖动逻辑
            if (element instanceof Wire) {
                const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
                const handled = element.onMouseDown(canvasCoords);
                if (handled) {
                    isDragging = true;
                    elementGroup.style.cursor = 'grabbing';
                    return;
                }
                return;
            }

            // 对于所有非Wire元件，使用完全相同的拖动逻辑
            const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
            const handled = (element as CircuitElement).onMouseDown(canvasCoords);
            
            if (handled) {
                isDragging = true;
                startScreenPos = { x: e.clientX, y: e.clientY };
                startPosition = { ...element.position };
                elementGroup.style.cursor = 'grabbing';
            }
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            
            const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
            
            // 检查是否真的在拖动
            const dragThreshold = 5;
            const hasMoved = Math.abs(e.clientX - startScreenPos.x) > dragThreshold || 
                            Math.abs(e.clientY - startScreenPos.y) > dragThreshold;
            
            if (hasMoved) {
                hasDragged = true;
            }
            
            // 使用统一的拖动逻辑，Wire和其他元件一样处理
            const handled = element.handleDrag(canvasCoords);
            if (handled) {
                if (element instanceof Wire) {
                    // Wire: 重新渲染
                    requestAnimationFrame(() => {
                        this.rerenderElement(elementGroup, element);
                    });
                } else {
                    // CircuitElement: 更新连接Pin的位置
                    this.updateConnectedPinsForElement(element);

                    // 同步更新 - 使用直接的位置属性
                    syncElementUpdates(elementGroup, element);
                }
            } else {
                // 元件不能拖动，停止拖动
                isDragging = false;
                elementGroup.style.cursor = '';
                return;
            }
        });

        /**
         * 同步元件更新（分区、Wire、渲染）- 被动模式版本
         * 使用直接的位置属性而不是姿态数据
         */
        const syncElementUpdates = (elementGroup: SVGGElement, element: CircuitElement) => {
            // 检查是否需要更新分区
            const oldKey = this.getPartitionKey(lastPosition.x, lastPosition.y);
            const newKey = this.getPartitionKey(element.position.x, element.position.y);
            if (oldKey !== newKey) {
                this.updateElementPartition(element, oldKey);
            }

            // 更新lastPosition
            lastPosition.x = element.position.x;
            lastPosition.y = element.position.y;

            // 更新连接到这个元件的所有Wire
            this.updateConnectedWiresForElement(element);

            // 使用节流优化渲染，减少闪烁
            const now = Date.now();
            if (now - lastRenderTime >= RENDER_THROTTLE) {
                requestAnimationFrame(() => {
                    this.rerenderElement(elementGroup, element);
                });
                lastRenderTime = now;
            }
        };

        document.addEventListener('mouseup', (e) => {
            if (element instanceof Wire && isDragging) {
                element.onMouseUp();
            }
            
            if (isDragging) {
                isDragging = false;
                // 恢复元件原有的光标样式，而不是重置为空字符串
                elementGroup.style.cursor = 'move';
                
                // 检查是否是点击（而不是拖动）
                const clickDuration = Date.now() - clickStartTime;
                const dragThreshold = 5; // 移动5像素以上算拖动
                const hasMoved = Math.abs(e.clientX - startScreenPos.x) > dragThreshold || 
                                Math.abs(e.clientY - startScreenPos.y) > dragThreshold;
                
                if (!hasMoved && clickDuration < 300) {
                    // 这是一个点击事件，显示属性面板
                    this.showPropertyPanel(element, e.clientX, e.clientY);
                }
            }
        });
    }



    /**
     * 设置Pin交互功能
     */
    private setupPinInteractions(elementGroup: SVGGElement, element: CircuitElement | Wire): void {
        // Wire类型没有pins，直接返回
        if (element instanceof Wire) {
            return;
        }
        
        // 等待DOM更新后再查找Pin元素
        setTimeout(() => {
            // 只查找已经标记为Pin的circle元素（带有data-pin-id属性）
            const pinElements = elementGroup.querySelectorAll('circle[data-pin-id]');
            
            pinElements.forEach((pinElement) => {
                const pinId = (pinElement as SVGCircleElement).getAttribute('data-pin-id');
                const pin = (element as CircuitElement).pins.find(p => p.id === pinId);
                if (!pin) return;
                
                // 确保Pin元素有正确的初始样式
                const circleElement = pinElement as SVGCircleElement;
                
                // 设置初始样式（如果没有的话）- 确保基本属性存在
                if (!circleElement.hasAttribute('r')) {
                    circleElement.setAttribute('r', '3');
                }
                if (!circleElement.hasAttribute('fill')) {
                    circleElement.setAttribute('fill', '#FF6347');
                }
                if (!circleElement.hasAttribute('stroke')) {
                    circleElement.setAttribute('stroke', '#000000');
                }
                if (!circleElement.hasAttribute('stroke-width')) {
                    circleElement.setAttribute('stroke-width', '2');
                }
                
                // 存储原始样式属性
                if (!circleElement.getAttribute('data-original-r')) {
                    circleElement.setAttribute('data-original-r', circleElement.getAttribute('r') || '3');
                    circleElement.setAttribute('data-original-fill', circleElement.getAttribute('fill') || '#FF6347');
                    circleElement.setAttribute('data-original-stroke', circleElement.getAttribute('stroke') || '#000000');
                    circleElement.setAttribute('data-original-stroke-width', circleElement.getAttribute('stroke-width') || '1');
                }
                
                // Pin点击事件
                pinElement.addEventListener('mousedown', (e) => {
                    e.stopPropagation(); // 阻止事件冒泡到元件拖动
                    this.startPinConnection(pin);
                });
                
                // Pin释放事件 - 完成连接
                pinElement.addEventListener('mouseup', (e) => {
                    e.stopPropagation(); // 阻止事件冒泡
                    this.completePinConnection(pin);
                });
                
                // 移除Pin的JavaScript hover事件处理，完全交给CSS处理
                // 避免JavaScript事件与CSS:hover伪类冲突导致的闪烁问题
            });
        }, 0);
    }

    /**
     * 开始Pin连接
     */
    private startPinConnection(pin: IPin): void {
        if (this.connectionManager.getState() === ConnectionState.Connecting) {
            // 如果已经在连接中，取消当前连接并开始新的连接
            this.connectionManager.cancelConnection();
        }
        // 开始新的连接
        this.connectionManager.startConnection(pin, this.canvas, (id: string) => {
            return globalMgr.getElementById(id);
        }, (sourcePin: IPin, targetPin: IPin) => {
            this.createWireBetweenPins(sourcePin, targetPin);
        });
    }

    /**
     * 显示属性面板（侧边滑出）
     */
    private showPropertyPanel(element: CircuitElement | Wire, mouseX: number, mouseY: number): void {
        // 直接显示属性面板，新的面板会自动在侧边滑出
        this.propertyPanel.show(element);
    }

    /**
     * 完成Pin连接
     */
    private completePinConnection(targetPin: IPin): void {
        if (this.connectionManager.getState() === ConnectionState.Connecting) {
            this.connectionManager.completeConnection(targetPin);
        }
    }
    


    /**
     * 主动更新连接到指定元件的所有Pin的位置
     * 当元件被主动拖动时，实时更新所有连接Pin的世界坐标
     */
    private updateConnectedPinsForElement(element: CircuitElement): void {
        console.log(`[CanvasManager] === 主动更新连接到 ${element.id} 的Pin位置 ===`);
        
        for (const pin of element.pins) {
            if (pin.connectedPins && pin.connectedPins.length > 0) {
                // 获取当前Pin的世界坐标
                const pinLocalPos = element.getPinPosition(pin);
                const pinWorldPos = {
                    x: element.position.x + pinLocalPos.x,
                    y: element.position.y + pinLocalPos.y
                };
                
                console.log(`[CanvasManager] 元件Pin ${pin.id} 世界坐标: (${pinWorldPos.x}, ${pinWorldPos.y})`);
                
                // 通知所有连接到这个Pin的Wire元件更新位置
                for (const connectedPin of pin.connectedPins) {
                    const connectedElement = globalMgr.getElementById(connectedPin.componentId);
                    if (connectedElement && connectedElement instanceof Wire) {
                        // 对于新的Wire架构，Wire会自动更新，不需要手动处理
                    } else if (connectedElement && !(connectedElement instanceof Wire)) {
                        // 对于非Wire元件，使用原有的局部坐标更新方式（向后兼容）
                        const connectedPinLocalPos = {
                            x: pinWorldPos.x - connectedElement.position.x,
                            y: pinWorldPos.y - connectedElement.position.y
                        };
                        
                        console.log(`[CanvasManager] 更新非Wire元件Pin ${connectedPin.componentId}:${connectedPin.id} 局部坐标到 (${connectedPinLocalPos.x}, ${connectedPinLocalPos.y})`);
                        connectedPin.position = connectedPinLocalPos;
                    }
                }
            }
        }
    }

    /**
     * 更新连接到指定元件的所有Wire
     */
    private updateConnectedWiresForElement(element: CircuitElement): void {
        console.log(`[CanvasManager] === 更新连接到 ${element.id} 的所有Wire ===`);
        
        // 更新所有Wire（包括新架构和传统架构）
        this.wireManager.renderAllWires();
    }



    /**
     * 在两个Pin之间创建Wire组件
     */
    private createWireBetweenPins(sourcePin: IPin, targetPin: IPin): void {
        // 使用新的Wire架构创建连接
        const wire = this.wireManager.createWireBetweenPins(
            sourcePin.id, 
            targetPin.id, 
            this.connectionStyle
        );
        
        if (wire) {
            console.log(`New wire created: ${wire.id} between ${sourcePin.id} and ${targetPin.id}`);
        }
    }
    


    /**
     * 高亮Pin
     */
    private highlightPin(pinElement: SVGCircleElement, state: string): void {
        // 移除所有状态类
        pinElement.classList.remove('connecting', 'valid-target', 'invalid-target');
        
        // 添加对应的状态类
        if (state !== 'default' && state !== 'hover') {
            pinElement.classList.add(state);
        }
        
        // 对于default状态，恢复原始属性
        if (state === 'default') {
            const originalRadius = pinElement.getAttribute('data-original-r');
            const originalFill = pinElement.getAttribute('data-original-fill');
            const originalStroke = pinElement.getAttribute('data-original-stroke');
            const originalStrokeWidth = pinElement.getAttribute('data-original-stroke-width');
            
            if (originalRadius) pinElement.setAttribute('r', originalRadius);
            if (originalFill) pinElement.setAttribute('fill', originalFill);
            if (originalStroke) pinElement.setAttribute('stroke', originalStroke);
            if (originalStrokeWidth) pinElement.setAttribute('stroke-width', originalStrokeWidth);
            
            pinElement.removeAttribute('opacity');
        }
    }

    /**
     * 查找指定位置的Pin - 利用分区系统优化性能
     */
    private findPinAtPosition(x: number, y: number): IPin | null {
        const tolerance = 10; // 像素容差
        
        // 首先获取目标位置附近的元件(利用分区系统)
        const nearbyElements = this.getElementsInArea(x, y, tolerance);
        
        // 在附近元件中查找匹配的Pin
        for (const element of nearbyElements) {
            for (const pin of element.pins) {
                const pinPos = element.getPinPosition(pin);
                const globalPos = {
                    x: element.position.x + pinPos.x,
                    y: element.position.y + pinPos.y
                };
                
                const distance = Math.sqrt(
                    Math.pow(x - globalPos.x, 2) + Math.pow(y - globalPos.y, 2)
                );
                
                if (distance <= tolerance) {
                    return pin;
                }
            }
        }
        
        return null;
    }

    /**
     * 重新渲染元件 - 被动渲染模式版本
     * 使用直接的位置属性而不是姿态数据
     */
    private rerenderElement(elementGroup: SVGGElement, element: CircuitElement | Wire): void {
        if (element instanceof Wire) {
            // Wire：使用新的render方法，render方法已经包含了完整的transform
            const newSvg = element.render();
            
            // 创建临时容器来解析新的SVG内容
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = newSvg;
            const newElementGroup = tempDiv.firstChild as SVGGElement;
            
            // 替换整个元素组
            if (newElementGroup) {
                elementGroup.replaceWith(newElementGroup);
                
                // 只重新设置Pin交互，不重复设置拖动事件
                this.setupPinInteractions(newElementGroup, element);
            }
        } else {
            // 对于CircuitElement，使用直接的位置和旋转属性
            const rotation = (element as any).rotation || 0; // 使用rotation属性，默认0
            elementGroup.setAttribute('transform', `translate(${element.position.x}, ${element.position.y}) rotate(${rotation})`);
            // 非Wire元件不需要重新设置拖动事件，只更新transform即可
        }
    }

    /**
     * 更新元件分区归属
     * @param element 要更新的元件
     * @param oldKey 旧分区键(可选)
     */
    private updateElementPartition(element: CircuitElement, oldKey?: string): void {
        // 从旧分区移除
        if (oldKey) {
            const oldPartition = this.partitions.get(oldKey);
            if (oldPartition) {
                const index = oldPartition.findIndex(e => e.id === element.id);
                if (index !== -1) {
                    oldPartition.splice(index, 1);
                }
            }
        }

        // 添加到新分区
        const newKey = this.getPartitionKey(element.position.x, element.position.y);
        if (!this.partitions.has(newKey)) {
            this.partitions.set(newKey, []);
        }
        this.partitions.get(newKey)?.push(element);
    }

    /**
     * 设置画布原点在编辑器窗口正中间
     */
    private setupCanvasOrigin(): void {
        // 等待DOM渲染完成后获取画布显示区域尺寸
        setTimeout(() => {
            const rect = this.canvas.getBoundingClientRect();
            const centerX = rect.width / 2;
            const centerY = rect.height / 2;
            
            // 设置viewBox，使画布对象原点显示在画布显示区域中心
            // viewBox定义了画布显示区域显示画布对象的哪个部分
            this.canvas.setAttribute('viewBox', `${-centerX} ${-centerY} ${rect.width} ${rect.height}`);
            
            // 初始化视口变换（画布对象相对于画布显示区域的变换）
            this.viewportTransform = { x: 0, y: 0, scale: 1 };
            this.updateViewportTransform();
        }, 100);
    }

    /**
     * 更新视口变换（画布对象相对于画布显示区域的变换）
     */
    private updateViewportTransform(): void {
        this.canvasContainer.setAttribute('transform', 
            `translate(${this.viewportTransform.x}, ${this.viewportTransform.y}) scale(${this.viewportTransform.scale})`
        );
    }

    /**
     * 将屏幕坐标转换为画布对象坐标
     */
    private screenToCanvas(screenX: number, screenY: number): { x: number, y: number } {
        const pt = this.canvas.createSVGPoint();
        pt.x = screenX;
        pt.y = screenY;
        
        // 转换到画布显示区域坐标
        const svgP = pt.matrixTransform(this.canvas.getScreenCTM()?.inverse());
        
        // 转换到画布对象坐标（考虑视口变换）
        const canvasX = (svgP.x - this.viewportTransform.x) / this.viewportTransform.scale;
        const canvasY = (svgP.y - this.viewportTransform.y) / this.viewportTransform.scale;
        
        return { x: canvasX, y: canvasY };
    }

    /**
     * 将画布对象坐标转换为屏幕坐标
     */
    private canvasToScreen(canvasX: number, canvasY: number): { x: number, y: number } {
        const pt = this.canvas.createSVGPoint();
        
        // 转换到画布显示区域坐标（考虑视口变换）
        const svgX = canvasX * this.viewportTransform.scale + this.viewportTransform.x;
        const svgY = canvasY * this.viewportTransform.scale + this.viewportTransform.y;
        
        pt.x = svgX;
        pt.y = svgY;
        
        // 转换到屏幕坐标
        const screenP = pt.matrixTransform(this.canvas.getScreenCTM() || new DOMMatrix());
        
        return { x: screenP.x, y: screenP.y };
    }

    /**
     * 设置画布拖动功能
     */
    private setupCanvasDrag(): void {
        this.canvas.addEventListener('mousedown', (e) => {
            // 检查是否点击在空白区域
            const target = e.target as SVGElement;
            
            // 检查目标是否是画布容器或画布本身，或者是没有data-element-id的元素（空白区域）
            const isCanvasArea = target === this.canvas || 
                                target === this.canvasContainer ||
                                (!target.closest('[data-element-id]') && 
                                 !target.closest('circle[data-pin-id]'));
            
            if (isCanvasArea) {
                // 转换屏幕坐标到画布对象坐标
                const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
                
                // 检查点击位置是否真的没有元件
                const hitResult = sceneHitTester.hitTestFirst(canvasCoords, 15);
                
                if (!hitResult || !hitResult.isHit) {
                    this.isDraggingCanvas = true;
                    this.dragStartPoint = { x: e.clientX, y: e.clientY };
                    this.dragStartTransform = { ...this.viewportTransform };
                    this.canvas.style.cursor = 'grabbing';
                    e.preventDefault();
                    e.stopPropagation();
                }
            }
        }, { capture: true });

        document.addEventListener('mousemove', (e) => {
            if (this.isDraggingCanvas) {
                const dx = e.clientX - this.dragStartPoint.x;
                const dy = e.clientY - this.dragStartPoint.y;
                
                // 更新视口变换（直接在屏幕空间计算偏移）
                this.viewportTransform.x = this.dragStartTransform.x + dx;
                this.viewportTransform.y = this.dragStartTransform.y + dy;
                
                this.updateViewportTransform();
                
                e.preventDefault();
            }
        });

        document.addEventListener('mouseup', () => {
            if (this.isDraggingCanvas) {
                this.isDraggingCanvas = false;
                this.canvas.style.cursor = 'grab';
            }
        });
    }


    /**
     * 设置事件监听器
     * 来自接口：ICircuitElement
     */
    private setupEventListeners(): void {
        // 确保画布和所有元件接收指针事件
        this.canvas.style.pointerEvents = 'auto';
        this.canvas.querySelectorAll('*').forEach(el => {
            (el as SVGElement).style.pointerEvents = 'auto';
        });

        // 添加事件监听器
        this.canvas.addEventListener('mousedown', (e) => {
            // 如果正在拖动画布，不处理其他事件
            if (this.isDraggingCanvas) {
                return;
            }

            // 转换屏幕坐标到画布对象坐标
            const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
            
            // 使用新的命中检测系统
            const hitResult = sceneHitTester.hitTestFirst(canvasCoords, 15);
            
            if (hitResult && hitResult.isHit) {
                if (hitResult.isComponentBodyHit) {
                    // 元件点击处理 - 直接调用setupElementDrag，不需要触发额外事件
                    const element = hitResult.target as CircuitElement;
                    const elementGroup = this.canvas.querySelector(`[data-element-id="${element.id}"]`) as SVGGElement;
                    if (elementGroup) {
                        this.setupElementDrag(elementGroup, element);
                        // 直接调用setupElementDrag中的逻辑，避免事件递归
                        this.handleElementMouseDown(elementGroup, element, e);
                    }
                }
                // Pin的点击由setupPinInteractions处理，这里不再处理
            } else {
                // 画布空白处点击 - 隐藏属性面板和取消连接
                this.propertyPanel.hide();
                if (this.connectionManager.getState() === ConnectionState.Connecting) {
                    this.connectionManager.cancelConnection();
                }
            }
        }, { capture: true });

        // 添加全局mouseup监听器来处理连接取消（当释放不在Pin上时）
        document.addEventListener('mouseup', (e) => {
            if (this.connectionManager.getState() === ConnectionState.Connecting) {
                // 检查鼠标是否在某个Pin上
                const target = e.target as SVGElement;
                const pinElement = target.closest('circle[data-pin-id]');
                if (!pinElement) {
                    // 如果不在Pin上释放，取消连接
                    this.connectionManager.cancelConnection();
                }
            }
        });
    }



    /**
     * 获取画布SVG元素，用于在其他组件中操作画布
     */
    public getCanvasElement(): SVGSVGElement {
        return this.canvas;
    }

    /**
     * 设置连线样式
     */
    public setConnectionStyle(style: ConnectionStyle): void {
        console.log('CanvasManager: Setting connection style to:', style);
        this.connectionStyle = style;
        this.connectionManager.setConnectionStyle(style);
        this.wireManager.setConnectionStyle(style);
    }

    /**
     * 获取当前连线样式
     */
    public getConnectionStyle(): ConnectionStyle {
        return this.connectionStyle;
    }

    /**
     * 设置拖放功能
     */
    private setupDragAndDrop(): void {
        dragManager.setupDrop(this.canvas, (toolType: string, x: number, y: number) => {
            this.createElementFromDrag(toolType, x, y);
        });
    }



    /**
     * 根据拖拽的工具类型创建元件
     */
    /**
     * 根据元件ID获取元件实例
     * 来自接口：ICircuitElement
     */
    getElementById(id: string): CircuitElement | undefined {
        return this.elements.find(e => e.id === id);
    }

    /**
     * 获取指定区域内的所有元件
     * @param x 区域中心x坐标
     * @param y 区域中心y坐标
     * @param radius 搜索半径(px)
     */
    getElementsInArea(x: number, y: number, radius: number): CircuitElement[] {
        const elements: CircuitElement[] = [];
        const gridRadius = Math.ceil(radius / this.gridSize);
        const centerGridX = Math.floor(x / this.gridSize);
        const centerGridY = Math.floor(y / this.gridSize);

        // 搜索周围分区
        for (let dx = -gridRadius; dx <= gridRadius; dx++) {
            for (let dy = -gridRadius; dy <= gridRadius; dy++) {
                const key = `${centerGridX + dx},${centerGridY + dy}`;
                const partitionElements = this.partitions.get(key);
                if (partitionElements) {
                    elements.push(...partitionElements);
                }
            }
        }

        // 过滤出实际在区域内的元件
        return elements.filter(element => {
            const distanceX = element.position.x - x;
            const distanceY = element.position.y - y;
            return Math.sqrt(distanceX * distanceX + distanceY * distanceY) <= radius;
        });
    }



    /**
     * 获取矩形区域内的所有元件
     * @param x1 矩形左上角x坐标
     * @param y1 矩形左上角y坐标
     * @param x2 矩形右下角x坐标
     * @param y2 矩形右下角y坐标
     */
    getElementsInRect(x1: number, y1: number, x2: number, y2: number): CircuitElement[] {
        const elements: CircuitElement[] = [];
        const minGridX = Math.floor(Math.min(x1, x2) / this.gridSize);
        const maxGridX = Math.floor(Math.max(x1, x2) / this.gridSize);
        const minGridY = Math.floor(Math.min(y1, y2) / this.gridSize);
        const maxGridY = Math.floor(Math.max(y1, y2) / this.gridSize);

        // 搜索矩形覆盖的分区
        for (let gridX = minGridX; gridX <= maxGridX; gridX++) {
            for (let gridY = minGridY; gridY <= maxGridY; gridY++) {
                const key = `${gridX},${gridY}`;
                const partitionElements = this.partitions.get(key);
                if (partitionElements) {
                    elements.push(...partitionElements);
                }
            }
        }

        // 过滤出实际在矩形区域内的元件
        return elements.filter(element => {
            return element.position.x >= Math.min(x1, x2) &&
                   element.position.x <= Math.max(x1, x2) &&
                   element.position.y >= Math.min(y1, y2) &&
                   element.position.y <= Math.max(y1, y2);
        });
    }



    /**
     * 调试方法：输出分区表信息到控制台
     */
    debugPartitions(): void {
        console.group('画布分区调试信息');
        console.log(`分区大小: ${this.gridSize}px`);
        console.log(`总分区数: ${this.partitions.size}`);
        console.log(`总元件数: ${this.elements.length}`);
        
        let totalElementsInPartitions = 0;
        this.partitions.forEach((elements, key) => {
            console.group(`分区 ${key}: ${elements.length}个元件`);
            elements.forEach(element => {
                console.log(`- ${element.constructor.name} [${element.id}]: (${element.position.x}, ${element.position.y})`);
            });
            console.groupEnd();
            totalElementsInPartitions += elements.length;
        });
        
        console.log(`分区内元件总数: ${totalElementsInPartitions}`);
        console.groupEnd();
    }

    /**
     * 设置连线样式监听器
     */
    private setupConnectionStyleListener(): void {
        window.addEventListener('circuit-editor:connection-style-changed', (event: Event) => {
            console.log('Connection style changed event received');
            const customEvent = event as CustomEvent;
            const { style } = customEvent.detail;
            console.log('Event detail style:', style);
            
            let connectionStyle: ConnectionStyle;
            
            switch (style) {
                case 'connection_bezier':
                    connectionStyle = ConnectionStyle.Bezier;
                    break;
                case 'connection_handdrawn':
                    connectionStyle = ConnectionStyle.Handdrawn;
                    break;
                default:
                    connectionStyle = ConnectionStyle.Straight;
                    break;
            }
            
            console.log('Setting connection style to:', connectionStyle);
            this.setConnectionStyle(connectionStyle);
        });
    }

    /**
     * 获取画布中的所有元件
     */
    public getElements(): CircuitElement[] {
        return [...this.elements];
    }

    /**
     * 将指定元件居中显示在画布显示区域
     */
    public centerOnElement(element: CircuitElement): void {
        // 等待DOM渲染完成后获取画布尺寸
        setTimeout(() => {
            // 由于viewBox已经将画布原点(0,0)设置在显示区域中心，
            // 所以要让元件居中，只需要将viewportTransform设置为元件位置的相反值
            // 这样元件位置(element.position.x, element.position.y)经过变换后会显示在中心
            
            // 考虑缩放的影响：需要将元件位置除以缩放比例
            const targetX = -element.position.x * this.viewportTransform.scale;
            const targetY = -element.position.y * this.viewportTransform.scale;
            
            // 更新视口变换
            this.viewportTransform.x = targetX;
            this.viewportTransform.y = targetY;
            
            this.updateViewportTransform();
        }, 100);
    }

    /**
     * 处理元件鼠标按下事件 - 避免事件递归
     */
    private handleElementMouseDown(elementGroup: SVGGElement, element: CircuitElement | Wire, e: MouseEvent): void {
        // 直接从 setupElementDrag 中提取的鼠标按下处理逻辑
        const target = e.target as SVGElement;
        if (target.closest('circle[data-pin-id]')) {
            // 如果是引脚点击，不启动拖动
            return;
        }

        // 对于Wire元件，使用Wire自己的拖动逻辑
        if (element instanceof Wire) {
            const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
            const handled = element.onMouseDown(canvasCoords);
            if (handled) {
                elementGroup.style.cursor = 'grabbing';
                return;
            }
            return;
        }

        // 对于CircuitElement元件，使用基础拖动逻辑
        const canvasCoords = this.screenToCanvas(e.clientX, e.clientY);
        const handled = element.onMouseDown(canvasCoords);
        
        if (handled) {
            elementGroup.style.cursor = 'grabbing';
        }
    }

    /**
     * 将调试方法暴露到全局窗口对象
     */
    exposeDebugMethods(): void {
        (window as any).debugCanvasPartitions = () => this.debugPartitions();
        (window as any).toggleContentPanel = () => this.contentPanel.toggle();
        console.log('调试指令已注册:');
        console.log('  debugCanvasPartitions() - 显示分区调试信息');
        console.log('  toggleContentPanel() - 切换画布内容面板');
    }

    private createElementFromDrag(toolType: string, x: number, y: number): void {
        // 转换屏幕坐标到画布对象坐标
        const canvasCoords = this.screenToCanvas(x, y);
        
        let element: CircuitElement | Wire | null = null;

        switch (toolType) {
            case 'resistor':
                element = new Resistor({
                    position: { x: canvasCoords.x, y: canvasCoords.y },
                    resistance: 1000
                });
                // 不再使用 setPose 方法，直接使用位置属性
                element.position = { x: canvasCoords.x, y: canvasCoords.y };
                break;
            case 'capacitor':
                element = new Capacitor({
                    position: { x: canvasCoords.x, y: canvasCoords.y },
                    capacitance: 1e-6
                });
                // 不再使用 setPose 方法，直接使用位置属性
                element.position = { x: canvasCoords.x, y: canvasCoords.y };
                break;
            case 'wire':
                element = new Wire({
                    startPoint: { x: canvasCoords.x - 25, y: canvasCoords.y },
                    endPoint: { x: canvasCoords.x + 25, y: canvasCoords.y },
                    style: this.connectionStyle,
                    resistance: 0.01
                });
                break;
            case 'voltage_source':
                element = new VoltageSource({
                    position: { x: canvasCoords.x, y: canvasCoords.y },
                    voltage: 5
                });
                // 不再使用 setPose 方法，直接使用位置属性
                element.position = { x: canvasCoords.x, y: canvasCoords.y };
                break;
            case 'current_source':
                element = new CurrentSource({
                    position: { x: canvasCoords.x, y: canvasCoords.y },
                    current: 0.1
                });
                // 不再使用 setPose 方法，直接使用位置属性
                element.position = { x: canvasCoords.x, y: canvasCoords.y };
                break;
            default:
                console.warn('Unknown tool type:', toolType);
                return;
        }

        if (element) {
            // 仅在此处添加元素，避免重复调用
            let shouldAddElement = false;
            
            if (element instanceof Wire) {
                // 对于Wire，检查ID重复即可
                shouldAddElement = !this.wires.some(w => w.id === element.id);
            } else {
                // 对于CircuitElement，检查位置和ID
                shouldAddElement = !this.elements.some(e => 
                    e.id === element?.id && 
                    e.position.x === element.position.x && 
                    e.position.y === element.position.y
                );
            }
            
            if (shouldAddElement) {
                this.addElement(element);
                // 发送元素添加事件
                window.dispatchEvent(new CustomEvent('circuit-editor:element-added', {
                    detail: { element }
                }));
            }
        } else {
            console.error('Failed to create element for tool type:', toolType);
        }
    }
}